﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO.Ports;
using IIControls.IAControl;
using Agrement;
using analy;
using System.Threading.Tasks;
using System.Web.Script.Serialization;
namespace Communicate
{
  public   class AgreePrivateBySerialPort:AgreePrivate  
    {



        /// <summary>
        /// <para>用法：</para>
        /// <para>1、实例化类，传入委托ReturnRes，该委托实现数据解析后的string和数据未解析前的byte[]</para>
        /// <para>2、调用SerialPortInit进行初始化串口</para>
        /// <para>3、调用ADDTasks、DELTaskMsg修改任务，在任务已经开始运行后允许新增任务，已经运行过的任务不允许删除</para>
        /// <para>4、调用TasksStart开始任务</para>
        /// </summary>
        /// <param name="RE"></param>
        public AgreePrivateBySerialPort(ReturnRes RE, int devicetype)
        {
            AgreePrivateBySerialPortInit(RE,devicetype);
        }

        public  void AgreePrivateBySerialPortInit(ReturnRes RE,int devicetype)
        {
            RR = RE;
            AgreePrivate.del_Send SendMsg = new Communicate.AgreePrivate.del_Send(SendBytes);
            AP = new Communicate.AgreePrivate(SendMsg, "0", devicetype);
        }

        /// <summary>
        /// 无参数构造函数，之后需要调用AgreePrivateBySerialPortInit进行初始化
        /// </summary>
        public AgreePrivateBySerialPort() { }


        /// <summary>
        /// 增加一个任务
        /// </summary>
        /// <param name="tasks"></param>
        public void ADDTasks(TaskMsg  tasks)
        {
            AP.ADDTaskMsg  (tasks);
        }
        /// <summary>
        /// 删除一个任务
        /// </summary>
        /// <param name="tasks"></param>
        public void DELTasks(TaskMsg tasks)
        {
            AP.DELTaskMsg(tasks);
        }
        /// <summary>
        /// 移除所有任务
        /// </summary>
        public bool  RemoveAllTask()
        {
          return   AP.RemoveAllMsg();
        }

        /// <summary>
        /// 开始执行任务
        /// </summary>
        public void TasksStart()
        {
            AP.SendTasks();
        }



        public  void SendBytes(byte[] data)
        {
            Send(data);
        }

      public   AgreePrivate AP;

       internal  SerialPort SP;

        /// <summary>
        /// 串口初始化
        /// </summary>
        /// <param name="BandRate">波特率</param>
        /// <param name="PortName">串口名称</param>
        /// <param name="DataBit">数据位</param>
        /// <param name="StopBit">停止位</param>
        /// <param name="ParityBit">校验位</param>
        /// <param name="AMT">使用协议</param>
        /// <returns>创建COM是否失败？True：成功，False：失败</returns>
        public Boolean  SerialPortInit(int BandRate, string PortName, int DataBit, StopBits StopBit, Parity ParityBit)
        {
            try
            {
                SP = new SerialPort(PortName, BandRate, ParityBit, DataBit, StopBit);
                SP.ReadTimeout = 500;   //500ms读不到数据，判断为超时          
                SP.Open();
                SP.DataReceived += SP_DataReceived;
                return true;
            }
            catch (Exception )
            {
                return false ;
            }
                   
        }

        /// <summary>
        /// 关闭串口
        /// </summary>
        /// <returns></returns>
        public Boolean SerialPortClose()
        {
            try
            {
                SP.Close();
                SP.DataReceived -= SP_DataReceived;
                return true;
            }
            catch (Exception)
            {
                return false;
            }
           
        }

        /// <summary>
        /// 接收到数据
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        internal virtual   void SP_DataReceived(object sender, SerialDataReceivedEventArgs e)
        {
            List<byte> ReceiveData = new List<byte>();
            while(true )
            {
                try
                {
                    ReceiveData.Add((byte)SP.ReadByte());
                }
                catch (Exception)
                {
                    break;
                }
            }

            Agrement.Send_Agreement AS = new Send_Agreement();
            //返回的数据进行分包处理
           List<byte[]> datas= AS.Read_Agreement(ReceiveData.ToArray());
            foreach ( byte[] data in datas )
            {
                AnalyAgreeMent AAM = new AnalyAgreeMent();
                string res = AAM.ReadAgreeMent(data);
                ReceiveStruct RS = new Communicate.AgreePrivateBySerialPort.ReceiveStruct()
                { AnalyResult = res, ReceiveData = ReceiveData.ToArray() };
                JavaScriptSerializer jsd = new JavaScriptSerializer();
                Dictionary<string, object> listres = jsd.Deserialize<Dictionary<string, object>>(res);
                if (listres.Keys.Contains("device_type") && listres.Keys.Contains("device_cmd") && listres.Keys.Contains("device_code"))
                {
                    if (Convert.ToInt32(listres["device_type"]) == 10 && Convert.ToInt32(listres["device_cmd"]) == 1)
                    {
                        AP.locks = 1;  //打包数据发送成功
                        if(AP.TaskPackage.Count>0)
                        {
                            AP.clearstatue(AP.TaskPackage[0].ToArray());
                            AP.TaskPackage.RemoveAt(0);
                        }
                    }
                    if (Convert.ToInt32(listres["device_type"]) == 10 && Convert.ToInt32(listres["device_cmd"]) == 6)
                        respondServer(listres);  //全部操作成功
                    if (Convert.ToInt32(listres["device_type"]) == 10 && Convert.ToInt32(listres["device_cmd"]) == 2)
                        respondServer(listres); //失败数据打包
                }
                RR(RS);
            }
        }

        private void respondServer(Dictionary<string, object> D)
        {
            string GPRSCode = "";
            byte types = Convert.ToByte(D["device_type"]);
            byte oper = Convert.ToByte(D["device_cmd"]);
            int[] ids = new int[] { Convert.ToInt32(D["device_code"].ToString().Substring(2, D["device_code"].ToString().Length - 2)) };
            AP.sendImmediatelyTask(GPRSCode, types, oper, ids, null);
        }

        public   ReturnRes RR;

      public   delegate void ReturnRes(ReceiveStruct RS);

       public  struct ReceiveStruct
        {
           public  string AnalyResult;
          public   byte[] ReceiveData;
        }


        /// <summary>
        /// 发送数据
        /// </summary>
        /// <param name="SendData"></param>
        /// <returns></returns>
        private  Boolean  Send(byte[] SendData)
        {
            try
            {
                SP.Write(SendData, 0, SendData.Length);
                return true ;
            }
            catch (Exception)
            {
                return false;
            }
           
        }


    }
}
